package com.hfzy.ihk.web.calldata.job;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.hfzy.ihk.common.constants.GlobalStatic;
import com.hfzy.ihk.common.core.elasticsearch.ElasticsearchLocalCache;
import com.hfzy.ihk.common.core.elasticsearch.ElasticsearchOperation;
import com.hfzy.ihk.common.core.elasticsearch.entity.OperationErrorMsg;
import com.hfzy.ihk.common.core.elasticsearch.repository.common.OperationErrorMsgRepository;
import com.hfzy.ihk.common.util.string.StringTools;
import com.hfzy.ihk.common.web.WebResult;
import com.hfzy.ihk.facade.calldata.entity.CallTaskDetail;
import com.hfzy.ihk.facade.calldata.enums.CallDataOperations;
import com.hfzy.ihk.facade.calldata.enums.CallDataTables;
import com.hfzy.ihk.web.calldata.biz.CallTaskDetailBiz;
import com.hfzy.ihk.web.calldata.constant.RedisKey;
import com.hfzy.ihk.web.calldata.vo.CallTaskDetailTotalVo;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by Administrator on 2018/8/16.
 */
@Component
@DependsOn({"callTaskDetailBiz"})
@Profile({"dev","pro"})
public class CallTaskRedisMsgJob {

    private final static Logger logger = LoggerFactory.getLogger(CallTaskRedisMsgJob.class);

    @Autowired
    CallTaskDetailBiz callTaskDetailBiz;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    OperationErrorMsgRepository operationErrorMsgRepository;

    @PostConstruct
    public void init() throws Exception {
        logger.info("init CallTaskRedisMsgJob bean");
    }

    /**
     * 定时根据通话任务包id,统计通话信息
     */
    @Scheduled(cron = "0 0/1 * * * ?")
    public void reTryCacheCallTaskRedisErrorMsg(){

        logger.debug("-----retry reTryCacheOptErrorMsg-------");

        if(ElasticsearchLocalCache.getCallTaskRedisErrorMsgMemoryCache().size()<=0) {
            return;
        }
        ElasticsearchLocalCache.getCallTaskRedisErrorMsgMemoryCache().forEach(map->{

            logger.debug("-----retry reTryCacheCallTaskRedisErrorMsg-------"+ JSON.toJSONString(map));
            try {
                callTaskDetailBiz.queueStatisticsCallHistory(map);
                ElasticsearchLocalCache.remove(map);
            } catch (Exception e) {
                e.printStackTrace();
            }

        });
        logger.debug("-----retry reTryCacheCallTaskRedisErrorMsg---over----");

    }

    /**
     * 定时根据通话任务包id,统计通话信息
     */
    @Scheduled(cron = "0 0 4 * * ?")
    public void operationCallTaskEnd(){
        logger.debug("-----operationCallTaskEnd start---");
        try{
            Map<String,Object> map = redisTemplate.opsForHash().entries(RedisKey.HAS_CALL_TASK_END);
            if(map!=null&&!map.isEmpty()){

                //获取还没有处理完的保存通话异常的信息
                BoolQueryBuilder builder = QueryBuilders.boolQuery();
                builder.must(QueryBuilders.termQuery("optTable", CallDataTables.CALL_HISTORY.getTableName()))
                        .must(QueryBuilders.termQuery("optMethod",CallDataOperations.addCallHistory.getOperationName()));
                Iterable<OperationErrorMsg> iterable = operationErrorMsgRepository.search(builder);
                List<OperationErrorMsg> list = Lists.newArrayList(iterable.iterator());
                if(ElasticsearchLocalCache.getOptErrorMsgMemoryCache().size()>0){
                    list.addAll(ElasticsearchLocalCache.getOptErrorMsgMemoryCache().stream()
                            .filter(o -> o.getOptTable().equals(CallDataTables.CALL_HISTORY.getTableName()) && o.getOptMethod().equals(CallDataOperations.addCallHistory.getOperationName()))
                            .collect(Collectors.toList()));
                }

                Set<String> set = new HashSet<>();
                if(StringTools.isNotempty(list)){
                    set.addAll(list.stream().map(operationErrorMsg -> {
                        String json = operationErrorMsg.getJsonArrayMessage();
                        if(StringTools.isNotNull(json)){
                            Map<String,Object> jsonMap = JSON.toJavaObject(JSON.parseObject(json),Map.class);
                            if(jsonMap.containsKey("callTaskId")){
                                return jsonMap.get("callTaskId").toString();
                            }
                        }
                        return "";
                    }).collect(Collectors.toSet()));
                }

                if(ElasticsearchLocalCache.getCallTaskRedisErrorMsgMemoryCache().size()>0){
                    set.addAll(ElasticsearchLocalCache.getCallTaskRedisErrorMsgMemoryCache().stream()
                            .map(map1 -> {
                                if(map1.containsKey("callTaskId")){
                                    return map1.get("callTaskId").toString();
                                }
                                return "";
                            }).collect(Collectors.toSet()));
                }

                for(String key : map.keySet()){
                    if(Boolean.valueOf(map.get(key).toString())){

                        if(StringTools.isNotempty(set)){
                            if(set.contains(key)){
                                continue;
                            }
                        }

                        Object object = redisTemplate.opsForHash().get(RedisKey.CALL_TASK,key);
                        if(object!=null){
                            CallTaskDetailTotalVo callTaskDetailTotalVo = JSON.toJavaObject(JSON.parseObject(object.toString()),CallTaskDetailTotalVo.class);
                            CallTaskDetail callTaskDetail = new CallTaskDetail();
                            BeanUtils.copyProperties(callTaskDetailTotalVo,callTaskDetail);
                            try {
                                WebResult webResult = callTaskDetailBiz.saveCallTaskDetail(callTaskDetail);
                                if(GlobalStatic.CODE_1.equals(webResult.getCode())){
                                    redisTemplate.opsForHash().delete(RedisKey.CALL_TASK,key);
                                    redisTemplate.opsForHash().delete(RedisKey.HAS_CALL_TASK_END,key);
                                }else{
                                    throw new RuntimeException();
                                }
                            }catch (Exception e){
                                logger.error("定时呼叫任务统计存入ES出错，错误信息：{}",e);
                            }
                        }
                    }
                }
            }
        }catch (Exception e){
            logger.error("定时呼叫任务统计处理出错，错误信息：{}",e);
        }
        logger.debug("-----operationCallTaskEnd end-----");
    }


}
